﻿using System;
using System.ComponentModel;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using System.Collections.Generic;

namespace GoodStuff.SharePoint2010.WebParts.RedirectWebPart
{
    /// <summary>
    /// Basic redirect WebPart which (when configured as active) will redirect all the users (that are not allowed to edit the page) to the configured url.
    /// </summary>
    [ToolboxItemAttribute(false)]
    public class RedirectWebPart : BaseWebPart
    {
        /// <summary>
        /// RedirectUrl
        /// </summary>
        /// <remarks>Virtual so that property can be overridden to enable change of attributes</remarks>
        [Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("RedirectUrl"), WebDescription("Redirect URL (may include http://)")]
        [Category("Properties")]
        public virtual string RedirectUrl { get; set; }

        /// <summary>
        /// Only redirects when active. Handy to disable the redirect (maybe temporarily) without the need to re-add the WebPart later on.
        /// </summary>
        /// <remarks>Virtual so that property can be overridden to enable change of attributes</remarks>
        [Personalizable(PersonalizationScope.Shared), WebBrowsable(true), WebDisplayName("Active?"), WebDescription("WebPart will only redirect when active")]
        [Category("Properties")]
        public virtual bool IsActive { get; set; }

        /// <summary>
        /// Message that will be shown when somebody with edit-page rights will load the page containing this RedirectWebPart, that somebody will not be
        /// redirected by this WebPart. Override to specify your own (translated) message. You have to specify {0} as placeholder for the redirecturl.
        /// </summary>
        public virtual string MessageNoRedirectFormatString
        {
            get
            {
                return "You won't be redirected to '{0}', probably because you can and probably want to edit this page. ";
            }
        }

        /// <summary>
        /// Override of default CreateChildControls()
        /// </summary>
        protected override void CreateChildControls()
        {
            bool abortRedirect = false;

            if (HttpContext.Current.User != null && HttpContext.Current.User.Identity.IsAuthenticated)
            {
                //Could be that some non publishing pages in the root of the sitecollection contain this WebPart, 
                //in that case, SPContext.Current.ListItem is NULL
                if (SPContext.Current.Item is SPListItem)
                {
                    // if the user has edit permission on this item, do not redirect this item, but show message.
                    abortRedirect = SPContext.Current.ListItem.DoesUserHavePermissions(SPBasePermissions.EditListItems);
                }
            }

            //Is Pagedesign allowed, abort redirect.
            if (this.WebPartManager != null && this.WebPartManager.DisplayMode.AllowPageDesign)
            {
                abortRedirect = true;
            }

            base.CreateChildControls();
            this.Controls.Clear();

            if (abortRedirect && this.IsActive && string.IsNullOrEmpty(this.RedirectUrl))
            {
                //WebPart is active, but no url has been configured
                this.Controls.Add(new LiteralControl("<span style=\"color:red\">RedirectWebPart is set to active, but no url to redirect to has been configured.</span><br/>"));
            }

            if (this.IsActive)
            {
                if (abortRedirect == false)
                {
                    if (!string.IsNullOrEmpty(this.RedirectUrl))
                    {
                        this.Page.Response.Redirect(this.RedirectUrl);
                    }
                }
                else
                {
                    this.Controls.Add(new LiteralControl(string.Format(this.MessageNoRedirectFormatString, this.RedirectUrl)));
                    this.Controls.Add(new LiteralControl(" Link: "));
                    this.Controls.Add(new HyperLink
                    {
                        NavigateUrl = this.RedirectUrl,
                        Text = this.RedirectUrl
                    });
                }
            }
        }
    }
}
